by Rob McGregor
In This Chapter
Graphics are extremely important in todays GUI OS world, and Windows is certainly no exception. Because Windows provides a graphical user interface (GUI) to the underlying operating system (OS) and hardware, graphics are the mainstay of Windows programs. This chapter explains how MFC packages and exposes device contexts and graphics objects. This chapter also introduces the basic concepts of creating, drawing, and using graphics in Windows.
Note:Four sample programs (VECTEXT1, RASTER1, BEZIER1, and BITMAP1) included on this books accompanying CD-ROM demonstrate all of the techniques described in this chapter, and more, with fully commented source code.
Everythingeven textpaints to the screen as graphics under Windows. The logical representation of a physical devices drawing surface is packaged into a complex data structure called a device context (DC). Windows provides several special datatypes and structures to represent and describe each of the fundamental Windows graphic objects (including pens, brushes, fonts, and bitmaps).
When a Windows program (including Windows itself) draws text and graphics to a display or some other device (such as a printer), it usually doesnt draw directly to the hardware as DOS programs do. In fact, applications that write directly to hardware are considered taboo in the world of Windows. Applications use a device context (DC) to represent a logical version of the physical device, be it a monitor, a printer, a plotter, or some other physical device. A DC contains information about the pen, brush, font, and bitmap currently selected for use on a device. MFC provides classes for several different types of DCs, and an application must explicitly ask for a DC before drawing anything to a device, even simply writing some text on the video display.
Device contexts arent limited to physical devices, however; DCs can refer to logical devices as well. An example of a logical device is a metafile, which is a collection of structures that stores a picture in a device-independent format. Another example is a bitmap, a collection of pixels that represents some graphic image. You can draw on a bitmap or a metafile as easily as you can draw on a display or a printer.
Four types of device contexts are supplied by the Win32 API:
Device contexts are used extensively by the Graphics Device Interface (GDI), a main component of the Windows architecture. Non-MFC Windows programs written in Standard C/C++ use a device context to give Windows the specifics of the device it should draw on. This device context is sent as a parameter to any of several GDI function calls provided by the Windows API. The GDI provides all the basic drawing function-ality for Windows; the DC represents the device, providing a layer of abstraction that insulates your applications from the nastiness of drawing directly to hardware. (Figure 4.1 shows this hardware abstraction.) The GDI provides this insulation by calling the appropriate device driver in response to Windows graphics function calls. This abstraction frees you from having to write low-level driver code to support each device youll draw toWindows includes drivers for and already knows how to draw hundreds of devices.
Figure 4.1 The layers of insulation between the hardware and an MFC application.
When writing MFC programs, you get an added benefit when using DCs and the GDI functions: The GDI functions are built right into the MFC DC classes as DC methods. This makes using the GDI functions very convenient, especially with the Intellisense pop-up lists provided by Microsoft Visual C++ 6.0 (see Figure 4.2).
Figure 4.2 Visual C++ Intellisense pop-up lists make using device context methods easier than ever.
MFC encapsulates the various types of device contexts provided by Windows into distinct DC classes that wrap a handle to a device context (HDC) within a C++ class. The class effectively contains information about the drawing attributes of a device. All drawing done in Windows is done on a device context, and all drawing methods are nicely wrapped into a DC object.
The following DC classes are the predefined MFC base classes for device contexts; they provide drawing and painting capabilities to MFC applications:
Figure 4.3 shows the relation of these classes in the MFC class hierarchy.
Figure 4.3 The hierarchy of MFC device context classes.
As you can see in Figure 4.3, the CDC class is the base class for the other DC classes. The CDC base class defines device context objects and provides methods for drawing on a display, a printer, or a windows client area.
All graphic output should be rendered using the class methods provided by CDC. These class methods provide services for using drawing tools, manipulating device contexts, type-safe GDI object selection, manipulating color and palettes, coordinate mapping and conversion, working with polygons and regions, drawing shapes, drawing text, working with fonts, handling metafiles, and more. The CDC class is a monster that encapsulates the GDI functions that use device contexts.
It might surprise you to know that a CDC object actually contains not one, but two device contexts. These DCs are stored as the class members described in Table 4.1; they allow a CDC object to point to two different devices simultaneously. It is this very useful property of an extra DC within a CDC object that makes advanced MFC features such as print preview so easy to achieve.